package org.folio.rest.impl;

import cn.hutool.core.util.StrUtil;
import io.vertx.core.AsyncResult;
import io.vertx.core.Context;
import io.vertx.core.Handler;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
import org.folio.cql2pgjson.CQL2PgJSON;
import org.folio.cql2pgjson.exception.FieldException;
import org.folio.rest.impl.other.PartyLogSave;
import org.folio.rest.jaxrs.model.AuxiliaryCollection;
import org.folio.rest.jaxrs.model.Errors;
import org.folio.rest.jaxrs.resource.PartyAuxiliary;
import org.folio.rest.persist.PgUtil;
import org.folio.rest.persist.PostgresClient;
import org.folio.rest.persist.cql.CQLWrapper;
import org.folio.rest.tools.messages.Messages;
import org.folio.rest.tools.utils.ValidationHelper;

import javax.ws.rs.core.Response;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static io.vertx.core.Future.succeededFuture;

/**
 * @author lee
 * @Classname AuxiliaryImpl
 * @Description TODO
 * @Date 2020/6/18 16:22
 * @Created by lee
 */
public class AuxiliaryImpl implements PartyAuxiliary {
    private final Logger logger = LoggerFactory.getLogger("modparty");
    private final Messages messages = Messages.getInstance();
    private static final String NOTIFY_TABLE = "auxiliary";

    private CQLWrapper getCQL(String query, int limit, int offset) throws FieldException {
        return new CQLWrapper(new CQL2PgJSON(NOTIFY_TABLE + ".jsonb"), query, limit, offset);
    }


    @Override
    public void postPartyAuxiliary(String lang,
                                   org.folio.rest.jaxrs.model.Auxiliary entity,
                                   Map<String, String> okapiHeaders,
                                   Handler<AsyncResult<Response>> asyncResultHandler,
                                   Context vertxContext) {
        String id = entity.getId();
        if (id == null || id.trim().isEmpty()) {
            id = UUID.randomUUID().toString();
        }
        PostgresClient pg = PgUtil.postgresClient(vertxContext, okapiHeaders);
        pg.save(NOTIFY_TABLE, id, entity, reply -> {
            if (reply.succeeded()) {
                String ret = reply.result();
                entity.setId(ret);
                asyncResultHandler.handle(succeededFuture(PostPartyAuxiliaryResponse
                        .respond201WithApplicationJson(entity, PostPartyAuxiliaryResponse.
                                headersFor201())));
                PartyLogSave.saveLog("新增名称为【" + entity.getName() + "】的资源 ",
                        2, entity.getMetadata(),entity.getOperator(), okapiHeaders, asyncResultHandler, pg);
            } else {

                ValidationHelper.handleError(reply.cause(), asyncResultHandler);
            }

        });
    }


    @Override
    public void getPartyAuxiliary(String query,
                                  int offset, int limit,
                                  String lang, Map<String, String> okapiHeaders,
                                  Handler<AsyncResult<Response>> asyncResultHandler,
                                  Context vertxContext) {
        CQLWrapper cql = null;
        if (StrUtil.isBlankOrUndefined(query)) {
            query = null;
        }
        try {
            cql = getCQL(query, limit, offset);
        } catch (Exception e) {
            ValidationHelper.handleError(e, asyncResultHandler);
            return;
        }
        PgUtil.postgresClient(vertxContext, okapiHeaders)
                .get(NOTIFY_TABLE, org.folio.rest.jaxrs.model.AuxiliaryGroup.class, new String[]{"*"}, cql,
                        true, false,
                        reply -> {
                            if (reply.succeeded()) {
                                AuxiliaryCollection notes = new AuxiliaryCollection();
                                List<org.folio.rest.jaxrs.model.AuxiliaryGroup> auxiliaryGroup
                                        = reply.result().getResults();
                                notes.setAuxiliaryGroup(auxiliaryGroup);
                                Integer totalRecords = reply.result().getResultInfo().getTotalRecords();
                                notes.setTotalRecords(totalRecords);
                                asyncResultHandler.handle(succeededFuture(
                                        GetPartyAuxiliaryResponse.respond200WithApplicationJson(notes)));
                            } else {
                                ValidationHelper.handleError(reply.cause(), asyncResultHandler);
                            }


                        });


    }


    @Override
    public void getPartyAuxiliaryById(String id,
                                      String lang, Map<String, String> okapiHeaders,
                                      Handler<AsyncResult<Response>> asyncResultHandler,
                                      Context vertxContext) {
        String noteId = id;
        if (noteId == null) {
            logger.error("The  id  is null , check your request id");
            Errors valErr = ValidationHelper.createValidationErrorMessage("id", noteId,
                    "Your request ID is empty, this is not allowed  ");
            asyncResultHandler.handle(succeededFuture(PutPartyAuxiliaryByIdResponse.respond404WithTextPlain(valErr)));
            return;
        }
        PgUtil.postgresClient(vertxContext, okapiHeaders)
                .getById(NOTIFY_TABLE, id, org.folio.rest.jaxrs.model.Auxiliary.class, callback -> {
                    if (callback.failed()) {
                        ValidationHelper.handleError(callback.cause(), asyncResultHandler);
                        return;
                    }
                    if (callback.result() == null) {
                        asyncResultHandler.handle(succeededFuture(GetPartyAuxiliaryByIdResponse.respond404WithTextPlain(id)));
                        return;
                    }
                    asyncResultHandler.handle(succeededFuture(GetPartyAuxiliaryByIdResponse.respond200WithApplicationJson(callback.result())));
                });
    }


    @Override
    public void deletePartyAuxiliaryById(String id,
                                         String lang, Map<String, String> okapiHeaders,
                                         Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {

        String noteId = id;
        if (noteId == null) {
            logger.error("the  id is null , check your request id");
            Errors valErr = ValidationHelper.createValidationErrorMessage("id", noteId,
                    "Your request ID is empty, this is not allowed  ");
            asyncResultHandler.handle(succeededFuture(PutPartyAuxiliaryByIdResponse.respond404WithTextPlain(valErr)));
            return;
        }
        PostgresClient postgresClient = PgUtil.postgresClient(vertxContext, okapiHeaders);
        postgresClient.delete(NOTIFY_TABLE, id, reply -> {
            if (reply.succeeded()) {
                if (reply.result().getUpdated() == 0) {
                    asyncResultHandler.handle(succeededFuture(DeletePartyAuxiliaryByIdResponse
                            .respond404WithTextPlain(id)));
                } else { // all ok
                    asyncResultHandler.handle(succeededFuture(
                            DeletePartyAuxiliaryByIdResponse.respond204()));
                    PartyLogSave.saveLog("删除编号为【" + id + "】的资源 ", 4,
                            null, okapiHeaders, asyncResultHandler, postgresClient);
                }
            } else {
                ValidationHelper.handleError(reply.cause(), asyncResultHandler);
            }
        });


    }

    
    @Override
    public void putPartyAuxiliaryById(String id, String lang,
                                      org.folio.rest.jaxrs.model.Auxiliary entity,
                                      Map<String, String> okapiHeaders,
                                      Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {

        String noteId = entity.getId();
        if (noteId != null && !noteId.equals(id)) {
            logger.error("Trying to change note Id from " + id + " to " + noteId);
            Errors valErr = ValidationHelper.createValidationErrorMessage("id", noteId,
                    "Can not change the id");
            asyncResultHandler.handle(succeededFuture(PutPartyAuxiliaryByIdResponse.respond404WithTextPlain(valErr)));
            return;
        }
        PostgresClient pg = PgUtil.postgresClient(vertxContext, okapiHeaders);
        pg.update(NOTIFY_TABLE, entity, id,
                reply -> {
                    if (reply.succeeded()) {
                        if (reply.result().getUpdated() == 0) {
                            asyncResultHandler.handle(succeededFuture(PutPartyAuxiliaryByIdResponse
                                    .respond404WithTextPlain(id)));
                        } else {
                            asyncResultHandler.handle(succeededFuture(
                                    PutPartyAuxiliaryByIdResponse.respond204()));
                            PartyLogSave.saveLog("修改名称为【" + entity.getName() + "】的资源 ",
                                    3,entity.getMetadata(),entity.getOperator(), okapiHeaders, asyncResultHandler, pg);
                        }
                    } else {
                        ValidationHelper.handleError(reply.cause(), asyncResultHandler);
                    }
                });
    }
}
